package com.dupengcheng.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import com.dupengcheng.auth.common.consts.CommConstant;
import com.dupengcheng.auth.common.consts.RedisConstants;
import com.dupengcheng.auth.common.enums.IsDeleteEnum;
import com.dupengcheng.auth.common.enums.StateEnum;
import com.dupengcheng.auth.domain.convert.AuthUserBOConvert;
import com.dupengcheng.auth.domain.entity.AuthUserBO;
import com.dupengcheng.auth.domain.redis.RedisUtil;
import com.dupengcheng.auth.domain.service.AuthUserDomainService;
import com.dupengcheng.auth.infra.basic.entity.*;
import com.dupengcheng.auth.infra.basic.service.AuthPermissionService;
import com.dupengcheng.auth.infra.basic.service.AuthRolePermissionService;
import com.dupengcheng.auth.infra.basic.service.AuthRoleService;
import com.dupengcheng.auth.infra.basic.service.AuthUserService;
import com.dupengcheng.auth.infra.basic.service.impl.AuthUserRoleServiceImpl;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.ap.shaded.freemarker.template.utility.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private AuthUserService userService;

    @Resource
    private RedisUtil redisUtil;



    @Resource
    private AuthRoleService roleService;
    @Resource
    private AuthUserRoleServiceImpl  userRoleService;

    @Resource
    private AuthPermissionService permissionService;
    @Resource
    private AuthRolePermissionService rolePermissionService;
    /**
     * 用户注册。
     * @param authUserBO
     *
     *
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(AuthUserBO authUserBO) {
        if (log.isInfoEnabled()){

            log.info("UserController.register.bo:{}",authUserBO);
        }
        authUserBO.setIsDeleted(IsDeleteEnum.UN_DELETE.getCode());
        authUserBO.setStatus(StateEnum.OPNE.getCode());
        if (StringUtils.isNotBlank(authUserBO.getPassword())){
            authUserBO.setPassword(SaSecureUtil.md5BySalt(authUserBO.getPassword(), CommConstant.SALT));
        }
        //先添加用户、再添加用户和角色的关联、此操作要加上事物。
        AuthUser authUser=AuthUserBOConvert.INSTANCE
                .convertBOtoEntity(authUserBO);
        userService.insert(authUser);
        Long userId=authUser.getId();
        //添加角色关联关系。
        List<AuthUserRole> authUserRoles=new LinkedList<>();
        List<AuthRole> authRoles=new LinkedList<>();
        Set<Long> permissionList=new HashSet<>();
        authUserBO.getAuthRoleIds().stream().forEach(
                e->{
                    AuthRole authRole = roleService.queryById(e.longValue());
                    authRoles.add(authRole);
                    AuthUserRole authUserRole=new AuthUserRole();
                    authUserRole.setUserId(userId);
                    authUserRole.setRoleId(e.longValue());
                    authUserRoles.add(authUserRole);
                    AuthRolePermission authRolePermission=new AuthRolePermission();

                    authRolePermission.setRoleId(e.longValue());
                    List<AuthRolePermission> authRolePermissions = rolePermissionService.queryByCondition(authRolePermission);
                    Long[] array = authRolePermissions.stream().map(AuthRolePermission::getPermissionId).toArray(Long[]::new);
                    Collections.addAll(permissionList,array);


                }
        );
        userRoleService.insertBatch(authUserRoles);

        //噻进redis
        String roleKey = redisUtil.buildKey(RedisConstants.AUTH_ROLE_PREFIX, authUserBO.getUserName());

        redisUtil.del(roleKey);
        redisUtil.set(roleKey,new Gson().toJson(authRoles));
        List<Long> collect = permissionList.stream().collect(Collectors.toList());
       List<AuthPermission> authPermissions= permissionService.queryByIds(collect);
        String permissionKey = redisUtil.buildKey(RedisConstants.AUTH_PERMISSION_PREFIX, authUser.getUserName());
        redisUtil.set(permissionKey,new Gson().toJson(authPermissions));

    }
}
